/**
 *
 *  Copyright (c) 2011, AstroDAbis
 *  All rights reserved.
 *
 *  Redistribution and use in source and binary forms, with or without modification,
 *  are permitted provided that the following conditions are met:
 *
 *      * Redistributions of source code must retain the above copyright notice,
 *        this list of conditions and the following disclaimer.
 *      * Redistributions in binary form must reproduce the above copyright notice,
 *        this list of conditions and the following disclaimer in the documentation
 *        and/or other materials provided with the distribution.
 *
 *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 *  ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 *  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 *  IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 *  INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 *  DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 *  OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 *  OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
package org.jiscinvolve.astrodabis.mallow.model.api;

import java.util.Date;
import java.util.EnumSet;

import java.util.Map;
import java.util.HashMap;

import org.jiscinvolve.astrodabis.mallow.model.tap.TapTable;
import org.jiscinvolve.astrodabis.mallow.model.tap.TapService;
import org.jiscinvolve.astrodabis.mallow.model.jpa.ManagedObject;

/**
 * Public interface for a Query.
 *
 */
public interface Query
extends ManagedObject
    {

    /**
     * Enum values for actions.
     *
     */
    enum Action {

        SAVE(),
        CLONE(),
        RUN(),
        FAIL(),
        COMPLETE(),
        CANCEL();

        };

    /**
     * Enum values for the Query status.
     *
     */
    enum Status {

        EDITING(),
        PENDING(),
        RUNNING(),
        FAILED(),
        COMPLETED(),
        CANCELLED();

        };

    /**
     * Allowed transitions.
     * Fudge to allow static initializer in an interface.
     * http://hhgtc.blogspot.com/2008/08/not-so-obvious-answer-to-can-java.html
     *
     */
    public static class Transitions {

        /**
         * Our map of allowed transitions.
         *
         */
        private static final Map<Status, EnumSet<Status>> map = new HashMap<Status, EnumSet<Status>>();

        /**
         * Our map of allowed transitions.
         *
         */
        public static Map<Status, EnumSet<Status>> map()
            {
            return map ;
            }

        static {

            map.put(
                Status.EDITING, 
                EnumSet.of(
                    Status.EDITING, 
                    Status.PENDING,
                    Status.CANCELLED
                    )
                );

            map.put(
                Status.PENDING, 
                EnumSet.of(
                    Status.PENDING, 
                    Status.RUNNING,
                    Status.FAILED,
                    Status.CANCELLED
                    )
                );

            map.put(
                Status.RUNNING, 
                EnumSet.of(
                    Status.RUNNING, 
                    Status.FAILED,
                    Status.COMPLETED,
                    Status.CANCELLED
                    )
                );

            map.put(
                Status.FAILED, 
                EnumSet.of(
                    Status.FAILED
                    )
                );

            map.put(
                Status.COMPLETED, 
                EnumSet.of(
                    Status.COMPLETED
                    )
                );

            map.put(
                Status.CANCELLED, 
                EnumSet.of(
                    Status.CANCELLED
                    )
                );
            }
        }

    /**
     * Get the Query name.
     *
     */
    public String name();

    /**
     * Get the Query description.
     *
     */
    public String text();

    /**
     * Get the Query table.
     *
     */
    public TapTable table();

    /**
     * Get the Query service.
     *
     */
    public TapService service();

    /**
     * Get the Query status.
     *
     */
    public Status status();

    /**
     * The Query results.
     *
     */
    public ResultManager results();

    /**
     * Run the query.
     *
     */
    public void run();

    /**
     * Cancel the query.
     *
     */
    public void cancel();

    /**
     * Update the Query and save it.
     *
     */
    public void update(QueryBean bean);

    /**
     * Update the Query with conditional save.
     *
     */
    public void update(QueryBean bean, boolean save);

    /**
     * Get the QueryTags for this query.
     *
     */
    public QueryTagManager tags();

    /**
     * The ADQL query head.
     *
     */
    public String head(); 

    /**
     * The ADQL where clause.
     *
     */
    public String where(); 

    /**
     * The ADQL query tail.
     *
     */
    public String tail(); 

    /**
     * The full ADQL query.
     *
     */
    public String query(); 



    }

